"""
Proxy management API routes
"""

from fastapi import APIRouter, HTTPException, status
from fastapi.responses import JSONResponse
from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field
import asyncio
import sys
import os

# Add parent directory to path for imports
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from pp_mcp.proxies.proxy_manager import ProxyConfig

# Create proxy API router with dedicated prefix
proxy_router = APIRouter(prefix="/proxies", tags=["Proxy Management"])

# Global variable to store proxy manager instance
_proxy_manager = None


# Pydantic models for API requests/responses
class CreateProxyRequest(BaseModel):
    """Request model for creating a new proxy."""

    id: str = Field(..., description="Unique identifier for the proxy")
    name: str = Field(..., description="Human-readable name for the proxy")
    description: str = Field(..., description="Description of the proxy")
    target_server: Dict[str, Any] = Field(
        ..., description="Target server configuration"
    )
    enabled: bool = Field(
        default=True, description="Whether the proxy should be enabled"
    )
    mount_path: str = Field(..., description="Path where the proxy will be mounted")


class UpdateProxyRequest(BaseModel):
    """Request model for updating proxy configuration."""

    name: Optional[str] = Field(None, description="Human-readable name for the proxy")
    description: Optional[str] = Field(None, description="Description of the proxy")
    target_server: Optional[Dict[str, Any]] = Field(
        None, description="Target server configuration"
    )
    enabled: Optional[bool] = Field(
        None, description="Whether the proxy should be enabled"
    )
    mount_path: Optional[str] = Field(
        None, description="Path where the proxy will be mounted"
    )


class ProxyResponse(BaseModel):
    """Response model for proxy information."""

    id: str
    name: str
    description: str
    mount_path: str
    enabled: bool
    running: bool
    target_server: Dict[str, Any]
    runtime_info: Optional[Dict[str, Any]] = None


class ProxySummaryResponse(BaseModel):
    """Response model for proxy summary."""

    total_proxies: int
    running_proxies: int
    enabled_proxies: int
    disabled_proxies: int
    stopped_proxies: int
    active_proxy_ids: List[str]


@proxy_router.post(
    "/", response_model=Dict[str, str], status_code=status.HTTP_201_CREATED
)
async def create_proxy(request: CreateProxyRequest):
    """Create a new proxy configuration."""
    try:
        config = ProxyConfig(
            id=request.id,
            name=request.name,
            description=request.description,
            target_server=request.target_server,
            enabled=request.enabled,
            mount_path=request.mount_path,
        )

        if not _proxy_manager.add_proxy_config(config):
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=f"Proxy with ID '{request.id}' already exists",
            )

        # Start proxy if enabled
        if request.enabled:
            success = await _proxy_manager.start_proxy(request.id)
            if not success:
                return {
                    "message": f"Proxy '{request.id}' created but failed to start",
                    "proxy_id": request.id,
                }

        return {
            "message": f"Proxy '{request.id}' created successfully",
            "proxy_id": request.id,
        }

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to create proxy: {str(e)}",
        )


@proxy_router.get("/", response_model=List[ProxyResponse])
async def list_proxies():
    """Get list of all proxy configurations."""
    try:
        proxies = []
        for config in _proxy_manager.list_proxy_configs():
            status_info = _proxy_manager.get_proxy_status(config.id)
            proxy_response = ProxyResponse(
                id=config.id,
                name=config.name,
                description=config.description,
                mount_path=config.mount_path,
                enabled=config.enabled,
                running=status_info.get("running", False),
                target_server=config.target_server,
                runtime_info=status_info.get("runtime_info"),
            )
            proxies.append(proxy_response)

        return proxies

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to list proxies: {str(e)}",
        )


@proxy_router.get("/{proxy_id}", response_model=ProxyResponse)
async def get_proxy_details(proxy_id: str):
    """Get detailed information about a specific proxy."""
    try:
        config = _proxy_manager.get_proxy_config(proxy_id)
        if not config:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        status_info = _proxy_manager.get_proxy_status(proxy_id)

        return ProxyResponse(
            id=config.id,
            name=config.name,
            description=config.description,
            mount_path=config.mount_path,
            enabled=config.enabled,
            running=status_info.get("running", False),
            target_server=config.target_server,
            runtime_info=status_info.get("runtime_info"),
        )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get proxy details: {str(e)}",
        )


@proxy_router.put("/{proxy_id}", response_model=Dict[str, str])
async def update_proxy(proxy_id: str, request: UpdateProxyRequest):
    """Update proxy configuration."""
    try:
        config = _proxy_manager.get_proxy_config(proxy_id)
        if not config:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        # Update configuration
        was_running = proxy_id in _proxy_manager.proxies

        if request.name is not None:
            config.name = request.name
        if request.description is not None:
            config.description = request.description
        if request.target_server is not None:
            config.target_server = request.target_server
        if request.mount_path is not None:
            config.mount_path = request.mount_path
        if request.enabled is not None:
            config.enabled = request.enabled

        # Save updated configuration
        _proxy_manager._save_config()

        # Restart proxy if it was running
        if was_running:
            await _proxy_manager.restart_proxy(proxy_id)
        elif config.enabled:
            await _proxy_manager.start_proxy(proxy_id)

        return {
            "message": f"Proxy '{proxy_id}' updated successfully",
            "proxy_id": proxy_id,
        }

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update proxy: {str(e)}",
        )


@proxy_router.delete("/{proxy_id}", response_model=Dict[str, str])
async def delete_proxy(proxy_id: str):
    """Delete a proxy configuration."""
    try:
        if not _proxy_manager.get_proxy_config(proxy_id):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        # Stop proxy if running
        if proxy_id in _proxy_manager.proxies:
            await _proxy_manager.stop_proxy(proxy_id)

        # Remove configuration
        _proxy_manager.remove_proxy_config(proxy_id)

        return {
            "message": f"Proxy '{proxy_id}' deleted successfully",
            "proxy_id": proxy_id,
        }

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to delete proxy: {str(e)}",
        )


@proxy_router.post("/{proxy_id}/start", response_model=Dict[str, str])
async def start_proxy(proxy_id: str):
    """Start a specific proxy."""
    try:
        if not _proxy_manager.get_proxy_config(proxy_id):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        if proxy_id in _proxy_manager.proxies:
            return {
                "message": f"Proxy '{proxy_id}' is already running",
                "proxy_id": proxy_id,
            }

        success = await _proxy_manager.start_proxy(proxy_id)
        if success:
            return {
                "message": f"Proxy '{proxy_id}' started successfully",
                "proxy_id": proxy_id,
            }
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Failed to start proxy '{proxy_id}'",
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to start proxy: {str(e)}",
        )


@proxy_router.post("/{proxy_id}/stop", response_model=Dict[str, str])
async def stop_proxy(proxy_id: str):
    """Stop a specific proxy."""
    try:
        if not _proxy_manager.get_proxy_config(proxy_id):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        if proxy_id not in _proxy_manager.proxies:
            return {
                "message": f"Proxy '{proxy_id}' is not running",
                "proxy_id": proxy_id,
            }

        success = await _proxy_manager.stop_proxy(proxy_id)
        if success:
            return {
                "message": f"Proxy '{proxy_id}' stopped successfully",
                "proxy_id": proxy_id,
            }
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Failed to stop proxy '{proxy_id}'",
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to stop proxy: {str(e)}",
        )


@proxy_router.post("/{proxy_id}/restart", response_model=Dict[str, str])
async def restart_proxy(proxy_id: str):
    """Restart a specific proxy."""
    try:
        if not _proxy_manager.get_proxy_config(proxy_id):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Proxy '{proxy_id}' not found",
            )

        success = await _proxy_manager.restart_proxy(proxy_id)
        if success:
            return {
                "message": f"Proxy '{proxy_id}' restarted successfully",
                "proxy_id": proxy_id,
            }
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Failed to restart proxy '{proxy_id}'",
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to restart proxy: {str(e)}",
        )


@proxy_router.get("/status/summary", response_model=ProxySummaryResponse)
async def get_proxy_summary():
    """Get summary of all proxy statuses."""
    try:
        total_proxies = len(_proxy_manager.proxy_configs)
        running_proxies = len(_proxy_manager.proxies)
        enabled_proxies = len(
            [c for c in _proxy_manager.proxy_configs.values() if c.enabled]
        )

        return ProxySummaryResponse(
            total_proxies=total_proxies,
            running_proxies=running_proxies,
            enabled_proxies=enabled_proxies,
            disabled_proxies=total_proxies - enabled_proxies,
            stopped_proxies=enabled_proxies - running_proxies,
            active_proxy_ids=list(_proxy_manager.proxies.keys()),
        )

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get proxy summary: {str(e)}",
        )


def setup_proxy_manager(proxy_manager):
    """Setup proxy manager for the routes."""
    global _proxy_manager
    _proxy_manager = proxy_manager


def get_proxy_router():
    """Get the configured proxy router."""
    return proxy_router
